#include "virginian.h"
#include "test/test.h"

namespace {

class CartesianTest : public VirginianTest {
	protected:

};

static const char *query_sql = "select test.col0,test1.col1 from test,test1";

TEST_F(CartesianTest, SQL) {
	virginian *v = doubledb_create();
	doubledb_addrows(v, 1,1);

	virg_vm *vm = virg_vm_init();
	virg_sql(v, query_sql, vm);

	EXPECT_TRUE(vm != NULL);

	//virg_print_stmt(vm);

	int i = 0;

	EXPECT_EQ(vm->stmt[i].op, OP_Table);
	EXPECT_EQ(vm->stmt[i++].p3, 0);
	EXPECT_EQ(vm->stmt[i].op, OP_Table);
	EXPECT_EQ(vm->stmt[i++].p3, 1);
	EXPECT_EQ(vm->stmt[i].op, OP_ResultColumn);
	EXPECT_EQ(strcmp(vm->stmt[i++].p4.s, "col0"), 0);
	EXPECT_EQ(vm->stmt[i].op, OP_ResultColumn);
	EXPECT_EQ(strcmp(vm->stmt[i++].p4.s, "col1"), 0);
	EXPECT_EQ(vm->stmt[i].op, OP_Parallel);

	virg_vm_cleanup(v, vm);
	doubledb_clear(v);
}

TEST_F(CartesianTest, ExecuteSingle) {
	virginian *v = doubledb_create();
	doubledb_addrows(v, 1, 1);

	virg_reader *r;
	virg_query(v, &r, query_sql);

	EXPECT_TRUE(r->res->fixed_columns == 2);
	EXPECT_EQ(r->res->fixed_type[0], VIRG_INT);

	virg_reader_row(v, r);
	int *x = (int*)&r->buffer[0];

	EXPECT_EQ(x[0], 0);

	virg_reader_free(v, r);
	virg_vm_cleanup(v, r->vm);
	free(r);

	doubledb_clear(v);
}

TEST_F(CartesianTest, ExecuteGPU) {
	virginian *v = doubledb_create();
	v->use_gpu 		= 1;
	v->use_mmap 	= 1;
	doubledb_addrows(v, 1, 1);

	virg_reader *r;
	virg_query(v, &r, query_sql);

	EXPECT_TRUE(r->res->fixed_columns == 2);
	EXPECT_EQ(r->res->fixed_type[0], VIRG_INT);

	virg_reader_row(v, r);
	int *x = (int*)&r->buffer[0];

	EXPECT_EQ(x[0], 0);

	virg_reader_free(v, r);
	virg_vm_cleanup(v, r->vm);
	free(r);

	doubledb_clear(v);
}

}
